package com.bankcard.bininfo.model;

import java.util.Objects;

/**
 * Represents the BIN (Bank Identification Number) information of a card.
 */
public final class BinInfo {
    /**
     * The Bank Identification Number (BIN).
     */
    private final String bin;

    /**
     * The brand of the card (e.g., VISA, MASTERCARD).
     */
    private final CardBrand cardBrand;

    /**
     * The type of the card (e.g., CREDIT, DEBIT).
     */
    private final CardType cardType;

    /**
     * The level of the card (e.g., STANDARD, GOLD).
     */
    private final CardLevel cardLevel;

    /**
     * Information about the card issuer.
     */
    private final IssuerInfo issuerInfo;

    private BinInfo(Builder builder) {
        this.bin = Objects.requireNonNull(builder.bin, "BIN cannot be null");
        this.cardBrand = builder.cardBrand;
        this.cardType = builder.cardType;
        this.cardLevel = builder.cardLevel;
        this.issuerInfo = builder.issuerInfo;
    }

    public String getBin() {
        return bin;
    }

    public CardBrand getCardBrand() {
        return cardBrand;
    }

    public CardType getCardType() {
        return cardType;
    }

    public CardLevel getCardLevel() {
        return cardLevel;
    }

    public IssuerInfo getIssuerInfo() {
        return issuerInfo;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BinInfo binInfo = (BinInfo) o;
        return bin.equals(binInfo.bin);
    }

    @Override
    public int hashCode() {
        return Objects.hash(bin);
    }

    @Override
    public String toString() {
        return "BinInfo{" +
                "bin='" + bin + '\'' +
                ", cardBrand=" + cardBrand +
                ", cardType=" + cardType +
                ", cardLevel=" + cardLevel +
                ", issuerInfo=" + issuerInfo +
                '}';
    }

    public static class Builder {
        private final String bin;
        private CardBrand cardBrand;
        private CardType cardType;
        private CardLevel cardLevel;
        private IssuerInfo issuerInfo;

        public Builder(String bin) {
            this.bin = bin;
        }

        public Builder cardBrand(CardBrand cardBrand) {
            this.cardBrand = cardBrand;
            return this;
        }

        public Builder cardType(CardType cardType) {
            this.cardType = cardType;
            return this;
        }

        public Builder cardLevel(CardLevel cardLevel) {
            this.cardLevel = cardLevel;
            return this;
        }

        public Builder issuerInfo(IssuerInfo issuerInfo) {
            this.issuerInfo = issuerInfo;
            return this;
        }

        public BinInfo build() {
            return new BinInfo(this);
        }
    }
}